﻿using System.Net.DnsToolkit.Packet;
using System.Net.DnsToolkit.Serializer.Stream.Extension;
using System.Net.DnsToolkit.Packet.Busy;

namespace System.Net.DnsToolkit.Bastard.PacketGenerator {

    /// <summary>
    /// Creates DNS packet that has domain name compression pointer
    /// that offset points outside of packet stream.
    /// 
    /// Some explaination on the bug :
    /// ---------------------------------------------------------
    ///   Normal packet, compression disabled
    /// ---------------------------------------------------------
    /// 
    /// Message {
    ///     Header,
    ///     Questions {
    ///         Question0 {
    ///             Name = "0.localhost.localnet"
    ///         }
    ///         Question1 {
    ///             Name = "1.localhost.localnet"
    ///         }
    ///     }
    ///     Answers,
    ///     Authorities,
    ///     Additionals
    /// }
    /// 
    /// ---------------------------------------------------------
    ///   Normal packet, compression enabled
    /// ---------------------------------------------------------
    /// 
    /// Message {
    ///     Header,
    ///     Questions {
    ///         Question0 {
    ///             Name = "0.localhost.localnet"
    ///         }
    ///         Question1 {
    ///             Name = "1." + pointer to Question0 offset 3 (localhost.localnet)
    ///         }
    ///     }
    ///     Answers,
    ///     Authorities,
    ///     Additionals
    /// }
    /// 
    /// ---------------------------------------------------------
    ///   Out of range domain pointer packet
    /// ---------------------------------------------------------
    /// 
    /// Message {
    ///     Header,
    ///     Questions {
    ///         Question0 {
    ///             Name = "0.localhost.localnet"
    ///         }
    ///         Question1 {
    ///             Name = "1." + pointer to 0xFF (outside of packet bytes)
    ///         }
    ///     }
    ///     Answers,
    ///     Authorities,
    ///     Additionals
    /// }
    /// 
    /// 
    /// 
    /// 
    /// </summary>
    public class DomainPointerOutOfRange : IPacketGenerator {

        public byte[] GetBytes() {
            byte[] bs = GetMessage().GetBytes();
            bs[41] = 0xFF; // byte 41 is domain name pointer,
            return bs;
        }


        public IMessage GetMessage() {

            var message = new Message();
            message.Questions.AddRange(
                new Question[] {
                    new Question {
                        QClass = QClassEnum.IN,
                        QType = QTypeEnum.A,
                        QName = new DomainName {
                            Name = "0.localhost.localnet"
                        }
                    },
                    new Question {
                        QClass = QClassEnum.IN,
                        QType = QTypeEnum.A,
                        QName = new DomainName {
                            Name = "1.localhost.localnet"
                        }
                    }
                }
            );
            message.Header.QuestionCount = (ushort)message.Questions.Count;


            return message;
        }

    }
}
